/* vim: set expandtab tabstop=4 softtabstop=4 shiftwidth=4: */
/* Copyright (C) 2012 Zongyou Yao. All rights reserved.     */

#ifndef MP_INCLUDED
#define MP_INCLUDED

#include <stdarg.h>
#include <stddef.h>
#include "except.h"
#include "fmt.h"

typedef unsigned char * mp_t;

extern const except_t mp_overflow;
extern const except_t mp_dividebyzero;

int mp_set(int n);
mp_t mp_new(unsigned long u);
mp_t mp_fromint(mp_t z, long v);
mp_t mp_fromintu(mp_t z, unsigned long u);
unsigned long mp_tointu(mp_t x);
long mp_toint(mp_t x);
mp_t mp_cvt(int m, mp_t z, mp_t x);
mp_t mp_cvtu(int m, mp_t z, mp_t x);
mp_t mp_add(mp_t z, mp_t x, mp_t y);
mp_t mp_sub(mp_t z, mp_t x, mp_t y);
mp_t mp_mul(mp_t z, mp_t x, mp_t y);
mp_t mp_div(mp_t z, mp_t x, mp_t y);
mp_t mp_mod(mp_t z, mp_t x, mp_t y);
mp_t mp_neg(mp_t z, mp_t x);
mp_t mp_addu(mp_t z, mp_t x, mp_t y);
mp_t mp_subu(mp_t z, mp_t x, mp_t y);
mp_t mp_mulu(mp_t z, mp_t x, mp_t y);
mp_t mp_divu(mp_t z, mp_t x, mp_t y);
mp_t mp_modu(mp_t z, mp_t x, mp_t y);
mp_t mp_mul2u(mp_t z, mp_t x, mp_t y);
mp_t mp_mul2(mp_t z, mp_t x, mp_t y);
mp_t mp_addi(mp_t z, mp_t x, long y);
mp_t mp_subi(mp_t z, mp_t x, long y);
mp_t mp_muli(mp_t z, mp_t x, long y);
mp_t mp_divi(mp_t z, mp_t x, long y);
mp_t mp_addui(mp_t z, mp_t x, unsigned long y);
mp_t mp_subui(mp_t z, mp_t x, unsigned long y);
mp_t mp_mului(mp_t z, mp_t x, unsigned long y);
mp_t mp_divui(mp_t z, mp_t x, unsigned long y);
long mp_modi(mp_t x, long y);
unsigned long mp_modui(mp_t x, unsigned long y);
int mp_cmp(mp_t x, mp_t y);
int mp_cmpi(mp_t x, long y);
int mp_cmpu(mp_t x, mp_t y);
int mp_cmpui(mp_t x, unsigned long y);

mp_t mp_and(mp_t z, mp_t x, mp_t y);
mp_t mp_or(mp_t z, mp_t x, mp_t y);
mp_t mp_xor(mp_t z, mp_t x, mp_t y);
mp_t mp_not(mp_t z, mp_t x);
mp_t mp_andi(mp_t z, mp_t x, unsigned long y);
mp_t mp_ori(mp_t z, mp_t x, unsigned long y);
mp_t mp_xori(mp_t z, mp_t x, unsigned long y);
mp_t mp_lshift(mp_t z, mp_t x, int s);
mp_t mp_rshift(mp_t z, mp_t x, int s);
mp_t mp_ashift(mp_t z, mp_t x, int s);

mp_t mp_fromstr(mp_t z, const char *str, int base, char **end);
char * mp_tostr(char *str, int size, int base, mp_t x);
void mp_fmt(int code, va_list_box *box, int put(int c, void *cl), void *cl, unsigned char flags[], int width, int precision);
void mp_fmtu(int code, va_list_box *box, int put(int c, void *cl), void *cl, unsigned char flags[], int width, int precision);

#endif
